package com.google.code.mochaccino.framework.ui.demo.pages;
/*
 * Copyright 2012 Claude Houle claude.houle@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import com.google.code.mochaccino.framework.freemarker.TemplateManager;
import com.google.code.mochaccino.framework.rest.Root;
import com.google.code.mochaccino.framework.rest.mime.MimeTypes;
import com.google.code.mochaccino.framework.ui.demo.SubjectUtil;
import com.google.code.mochaccino.framework.ui.demo.pages.UserSettingsService.UserInfo;
import com.google.code.mochaccino.framework.ui.freemarker.TemplateOutput;
import com.google.code.mochaccino.framework.ui.freemarker.TemplateUtil;
import com.google.code.mochaccino.framework.ui.i18n.ResourceBundleUtil;
import com.google.code.mochaccino.framework.ui.services.ServiceResult;
import com.google.code.mochaccino.framework.ui.services.form.FormSubmitResult;
import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.CollectionModel;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;


/**
 *
 */
@Path( UserSettings.PATH )
public class UserSettings {

	public static final String PRIV_EDIT_INFO     = "UserSettingsEditInfo";
	public static final String PRIV_EDIT_MODULES  = "UserSettingsEditModules";
	public static final String PRIV_EDIT_PASSWORD = "UserSettingsEditPassword";

	public static final String PATH_EDIT_PWD_HTML     = "/{id}/edit/password.html";
	public static final String PATH_EDIT_MODULES_HTML = "/{id}/edit/modules.html";
	public static final String PATH_EDIT_INFO_HTML    = "/{id}/edit/info.html";
	public static final String PATH_EDIT_INFO         = "/{id}/edit/info";

	public static final String PATH                   = "/user-settings";
	public static final String PATH_EDIT_PWD_LESS     = "/edit/password.less";
	public static final String PATH_EDIT_MODULES_LESS = "/edit/modules.less";
	public static final String PATH_EDIT_INFO_LESS    = "/edit/info.less";

	/** The Frame Service */
	private FrameService frame = null;

	/** Template Manager */
	private TemplateManager manager = null;

	@Inject
	public UserSettings( UserSettingsService service, FrameService frame, TemplateManager manager ) {
		this.frame = frame;
		this.manager = manager;
		this.service = service;
	}

	/** The Login Service */
	private UserSettingsService service = null;

	@POST
	@Path( PATH_EDIT_INFO )
	@Consumes( MediaType.APPLICATION_JSON )
	@Produces( MediaType.APPLICATION_JSON )
	@RequiresPermissions( value = PRIV_EDIT_INFO )

	public Response info( UserInfo info ) {

		Locale locale = SubjectUtil.getLocale();
		FormSubmitResult result = new FormSubmitResult();
		ResourceBundle bundle = ResourceBundleUtil.getResourceBundle( "web/pages/usersettings/user-settings-info", locale );

		if ( info.getUsername() == null || info.getUsername().trim().length() == 0 ) {
			result.add( "username", bundle.getString( "MsgMandatory" ) );
		}

		if ( info.getEmail() == null || info.getEmail().trim().length() == 0 ) {
			result.add( "email", bundle.getString( "MsgMandatory" ) );
		}

		if ( info.getTimeout() == null ) {
			result.add( "timeout", bundle.getString( "MsgMandatory" ) );
		}

		if ( info.getTimeout() < service.getMinimumConsoleTimeout() || info.getTimeout() > service.getMaximumConsoleTimeout() ) {
			result.add( "timeout",
			            MessageFormat.format( bundle.getString( "MsgTimeoutInvalid" ),
			                                  new Object[] { service.getMinimumConsoleTimeout(),
			                                                 service.getMaximumConsoleTimeout() } ) );
		}

		if ( info.getLanguage() == null || info.getLanguage().trim().length() == 0 ) {
			result.add( "language", bundle.getString( "MsgMandatory" ) );
		} else {

			boolean found = false;
			for ( Locale loc : service.getAvailableLocale() ) {
				if ( loc.toString().equals( info.getLanguage().trim() ) ) {
					found = true;
					break;
				}
			}

			if ( !found ) {
				result.add( "language", bundle.getString( "MsgInvalidLanguage" ) );
			}
		}

		if ( result.getErrors().size() > 0 ) {
			ResponseBuilder response = Response.serverError();
			response.type( MediaType.APPLICATION_JSON );
			response.entity( result );
			return response.build();
		}

		ServiceResult serviceResult = service.saveUserInfo( info, locale );
		result.add( serviceResult );
		if ( result.getErrors().size() > 0 ) {
			ResponseBuilder response = Response.serverError();
			response.type( MediaType.APPLICATION_JSON );
			response.entity( result );
			return response.build();
		}

		return Response.ok().build();
	}

	@GET
	@Path( PATH_EDIT_INFO_HTML )
	@Produces( MimeTypes.TYPE_HTML )
	@RequiresPermissions( value = PRIV_EDIT_INFO )

	public Response info( @QueryParam( "lang" ) String lang, @PathParam( "id" ) String userId ) {
		UserInfo userInfo = service.getUserInfo( userId );
		if ( userInfo == null ) {
			return Response.status( Status.NOT_FOUND ).build();
		}

		Object credential = SecurityUtils.getSubject().getPrincipal();
		Locale loc = SubjectUtil.setLocale( lang );

		Map<String,Object> parameters = new HashMap<String,Object>();
		parameters.put( "info", userInfo );
		parameters.put( "languages", TemplateUtil.getLocaleListModel( service.getAvailableLocale(), userInfo.getLanguage() ) );
		parameters.put( "nodes", new CollectionModel( frame.getTreeNodes( credential ), BeansWrapper.getDefaultInstance() ) );
		parameters.put( "username", frame.getFullName( credential ) );
		parameters.put( "environment", frame.getEnvironment() );
		parameters.put( "timestamp", new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" ).format( new Date() ) );
		parameters.put( "i18n", ResourceBundleUtil.getResourceBundleModel( "web/pages/usersettings/user-settings-info", loc ) );
		parameters.put( "i18n_header", ResourceBundleUtil.getResourceBundleModel( "web/pages/frame/header", loc ) );
		parameters.put( "urlLogout", Root.PATH_LOGOUT );
		parameters.put( "urlSettings", frame.getSettingsUrl( credential ) );
		parameters.put( "urlHelp", frame.getHelpUrl() );
		parameters.put( "hideTree", Boolean.FALSE );
		parameters.put( "minTimeout", String.valueOf( service.getMinimumConsoleTimeout() ) );
		parameters.put( "maxTimeout", String.valueOf( service.getMaximumConsoleTimeout() ) );

		return Response.ok().entity( new TemplateOutput( manager, "/web/pages/usersettings/user-settings-info.html.ftl", parameters ) ).build();
	}

	@GET
	@Path( PATH_EDIT_INFO_LESS )
	@Produces( MimeTypes.TYPE_CSS )
	@RequiresPermissions( value = PRIV_EDIT_INFO )

	public Response infoStyle() {
		return Response.ok().entity( new TemplateOutput( manager, "/web/pages/usersettings/user-settings-info.less.ftl" ) ).build();
	}

	@GET
	@Path( PATH_EDIT_MODULES_HTML )
	@Produces( MimeTypes.TYPE_HTML )
	@RequiresPermissions( value = PRIV_EDIT_MODULES )

	public Response module( @QueryParam( "lang" ) String lang, @PathParam( "id" ) String userId ) {
		Object credential = SecurityUtils.getSubject().getPrincipal();
		Locale loc = SubjectUtil.getLocale();
		Map<String,Object> parameters = new HashMap<String,Object>();
		parameters.put( "nodes", new CollectionModel( frame.getTreeNodes( credential ), BeansWrapper.getDefaultInstance() ) );
		parameters.put( "username", frame.getFullName( credential ) );
		parameters.put( "environment", frame.getEnvironment() );
		parameters.put( "timestamp", new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" ).format( new Date() ) );
		parameters.put( "i18n", ResourceBundleUtil.getResourceBundleModel( "web/pages/usersettings/user-settings-module", loc ) );
		parameters.put( "i18n_header", ResourceBundleUtil.getResourceBundleModel( "web/pages/frame/header", loc ) );
		parameters.put( "urlLogout", Root.PATH_LOGOUT );
		parameters.put( "urlSettings", frame.getSettingsUrl( credential ) );
		parameters.put( "urlHelp", frame.getHelpUrl() );
		parameters.put( "hideTree", Boolean.FALSE );
		return Response.ok().entity( new TemplateOutput( manager, "/web/pages/usersettings/user-settings-module.html.ftl", parameters ) ).build();
	}

	@GET
	@Path( PATH_EDIT_MODULES_LESS )
	@Produces( MimeTypes.TYPE_CSS )
	@RequiresPermissions( value = PRIV_EDIT_MODULES )

	public Response moduleStyle() {
		return Response.ok().entity( new TemplateOutput( manager, "/web/pages/usersettings/user-settings-module.less.ftl" ) ).build();
	}

	@GET
	@Path( PATH_EDIT_PWD_HTML )
	@Produces( MimeTypes.TYPE_HTML )
	@RequiresPermissions( value = PRIV_EDIT_PASSWORD )

	public Response password( @QueryParam( "lang" ) String lang, @PathParam( "id" ) String userId ) {
		Object credential = SecurityUtils.getSubject().getPrincipal();
		Locale loc = SubjectUtil.getLocale();
		Map<String,Object> parameters = new HashMap<String,Object>();
		parameters.put( "nodes", new CollectionModel( frame.getTreeNodes( credential ), BeansWrapper.getDefaultInstance() ) );
		parameters.put( "username", frame.getFullName( credential ) );
		parameters.put( "environment", frame.getEnvironment() );
		parameters.put( "timestamp", new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" ).format( new Date() ) );
		parameters.put( "i18n", ResourceBundleUtil.getResourceBundleModel( "web/pages/usersettings/user-settings-password", loc ) );
		parameters.put( "i18n_header", ResourceBundleUtil.getResourceBundleModel( "web/pages/frame/header", loc ) );
		parameters.put( "urlLogout", Root.PATH_LOGOUT );
		parameters.put( "urlSettings", frame.getSettingsUrl( credential ) );
		parameters.put( "urlHelp", frame.getHelpUrl() );
		parameters.put( "hideTree", Boolean.FALSE );
		return Response.ok().entity( new TemplateOutput( manager, "/web/pages/usersettings/user-settings-password.html.ftl", parameters ) ).build();
	}

	@GET
	@Path( PATH_EDIT_PWD_LESS )
	@Produces( MimeTypes.TYPE_CSS )
	@RequiresPermissions( value = PRIV_EDIT_PASSWORD )

	public Response passwordStyle() {
		return Response.ok().entity( new TemplateOutput( manager, "/web/pages/usersettings/user-settings-password.less.ftl" ) ).build();
	}
}
